using System.Collections;
using UnityEngine;

public class Player : Entity
{
    public GameObject Sword { get; private set; }
    public SkillManager SkillManager { get; private set; }
    public Inventory Inventory { get; private set; }
    public new PlayerFx Fx => (PlayerFx)base.Fx;
    [Header("Attack details")] public Vector2[] attackMovement;
    public float counterAttackDuration = 0.2f;
    public bool IsBusy { get; private set; }
    [Header("Move info")] public float moveSpeed = 8;
    public float jumpForce = 17;
    internal bool IsJumping;
    public float swordReturnImpact = 2f;
    private float defaultMoveSpeed;
    private float defaultJumpForce;
    [Header("Dash info")] public float dashSpeed = 25;
    public float dashDuration = 0.2f;
    private float defaultDashSpeed;
    public float DashDir { get; private set; }
    public PlayerStateMachine StateMachine { get; private set; }
    public PlayerIdleState IdleState { get; private set; }
    public PlayerMoveState MoveState { get; private set; }
    public PlayerGroundedState GroundedState { get; private set; }
    public PlayerJumpState JumpState { get; private set; }
    public PlayerAirState AirState { get; private set; }
    // ReSharper disable once MemberCanBePrivate.Global
    public PlayerDashState DashState { get; private set; }
    // ReSharper disable once IdentifierTypo
    public PlayerWallslideState WallslideState { get; private set; }
    public PlayerWallJumpState WallJumpState { get; private set; }
    public PlayerPrimaryAttackState PrimaryAttackState { get; private set; }
    public PlayerCounterAttackState CounterAttackState { get; private set; }
    public PlayerAimSwordState AimSwordState { get; private set; }
    // ReSharper disable once MemberCanBePrivate.Global
    public PlayerCatchSwordState CatchSwordState { get; private set; }
    // ReSharper disable once IdentifierTypo
    public PlayerBlackholeState BlackholeState { get; private set; }
    // ReSharper disable once MemberCanBePrivate.Global
    public PlayerDeadState PlayerDeadState { get; private set; }

    protected override void Awake()
    {
        base.Awake();
        SkillManager = FindAnyObjectByType<SkillManager>();
        Inventory = FindAnyObjectByType<Inventory>();
        // Fx = GetComponent<PlayerFx>();
        StateMachine = new PlayerStateMachine();
        IdleState = new PlayerIdleState(this, "idle");
        MoveState = new PlayerMoveState(this, "move");
        GroundedState = new PlayerGroundedState(this, "idle");
        JumpState = new PlayerJumpState(this, "jump");
        AirState = new PlayerAirState(this, "jump");
        DashState = new PlayerDashState(this, "dash");
        WallslideState = new PlayerWallslideState(this, "wallslide");
        WallJumpState = new PlayerWallJumpState(this, "jump");
        PrimaryAttackState = new PlayerPrimaryAttackState(this, "attack");
        CounterAttackState = new PlayerCounterAttackState(this, "counterAttack");
        AimSwordState = new PlayerAimSwordState(this, "aimSword");
        CatchSwordState = new PlayerCatchSwordState(this, "catchSword");
        BlackholeState = new PlayerBlackholeState(this, "jump");
        PlayerDeadState = new PlayerDeadState(this, "dead");
        StateMachine.Initialize(IdleState);
    }

    protected void Start()
    {
        defaultMoveSpeed = moveSpeed;
        defaultJumpForce = jumpForce;
        defaultDashSpeed = dashSpeed;
    }

    private void Update()
    {
        if (Time.timeScale == 0f) return;
        StateMachine.CurrentState.Update();
        CheckForDashInput();
        if (Input.GetKeyDown(KeyCode.F) && SkillManager.Crystal.CrystalUnlocked)
        {
            _ = SkillManager.Crystal.CanUseSkill();
        }
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            Inventory.UseFlask();
        }
    }

    public override void SlowEntityBy(float slowPercentage, float slowDuration)
    {
        moveSpeed *= 1 - slowPercentage;
        jumpForce *= 1 - slowPercentage;
        dashSpeed *= 1 - slowPercentage;
        Anim.speed *= 1 - slowPercentage;
        Invoke(nameof(ReturnDefaultSpeed), slowDuration);
    }

    protected override void ReturnDefaultSpeed()
    {
        base.ReturnDefaultSpeed();
        moveSpeed = defaultMoveSpeed;
        jumpForce = defaultJumpForce;
        dashSpeed = defaultDashSpeed;
    }

    public void AssignNewSword(GameObject newSword)
    {
        Sword = newSword;
    }

    public void CatchTheSword()
    {
        StateMachine.ChangeState(CatchSwordState);
        Destroy(Sword);
    }

    public IEnumerator BusyFor(float seconds)
    {
        IsBusy = true;
        yield return new WaitForSeconds(seconds);
        IsBusy = false;
    }

    public void SetPosition(Vector3 position) => transform.position = position;

    public void AnimationTrigger() => StateMachine.CurrentState.AnimationFinishedTrigger();

    private void CheckForDashInput()
    {
        if (IsWallDetected()) return;
        if (!SkillManager.Dash.DashUnlocked) return;
        if (Input.GetKeyDown(KeyCode.LeftShift) && SkillManager.Dash.CanUseSkill())
        {
            DashDir = Input.GetAxisRaw("Horizontal");
            if (DashDir == 0)
            {
                DashDir = FacingDirection;
            }
            StateMachine.ChangeState(DashState);
        }
    }

    public override void Die()
    {
        StateMachine.ChangeState(PlayerDeadState);
    }
}